#ifndef VEC3_HPP_
#define VEC3_HPP_

#include <string>
#include <iostream>
#include <array>

namespace gmath
{
  template <class T> class Vec3
  {
    public:
      Vec3();
      Vec3(T value);
      Vec3(T x, T y, T z);
      Vec3(T* ptr);

      const std::array<T, 3>& getData() const;
      void setData(const std::array<T, 3> data);
      void setData(T value);
      void setData(T x, T y, T z);
      void setData(T* ptr);

      T length();
      T dot(Vec3& v2);
      Vec3 cross(Vec3& v2);

      std::string toString();

      Vec3 operator+(Vec3& v2);
      Vec3 operator-(Vec3& v2);
      Vec3 operator*(T a);
      Vec3 operator/(T a);
      Vec3 operator+=(Vec3& v2);
      Vec3 operator-=(Vec3& v2);
      Vec3 operator*=(T a);
      Vec3 operator/=(T a);
      template<typename J> friend std::ostream& 
          operator<<(std::ostream& out, Vec3<J> v);

    private:
      std::array<T, 3> data_;
  };

  typedef Vec3<float> Vec3f;
  typedef Vec3<double> Vec3d;
  typedef Vec3<int> Vec3i;
}

#include "Vec3.inl"

#endif
